﻿function AzureProxyChannel() {

    var sharedProxy = "proxy/";
    var localProxy = "http://127.0.0.1:45612/";

    var proxyType = "shared";

    function parseRequest(request) {
        var responseText = request;
        return responseText;
    }

    function getBaseUrl() {
        switch (proxyType) {
            case 'shared':
                return sharedProxy;
            case 'local':
                return localProxy;
            default:
                return sharedProxy;
        }
    }

    function getDownloadUrl(request) {

        var headers = request.headers;

        var url = getBaseUrl() + 'download/?u=' + encodeURIComponent(request.uri.getUrl());

        var date = headers['Date'];
        if (date) {
            url += '&d=' + encodeURIComponent(date);
        }

        var msDate = headers['x-ms-date'];
        if (msDate) {
            url += '&md=' + encodeURIComponent(msDate);
        }

        var version = headers['x-ms-version'];
        if (version) {
            url += '&v=' + encodeURIComponent(version);
        }

        var authorization = headers['Authorization'];
        if (authorization) {
            url += '&a=' + encodeURIComponent(authorization);
        }

        var downloadName = request.downloadName;
        if (downloadName) {
            url += '&n=' + encodeURIComponent(downloadName);
        }

        url += '&rnd=' + Math.random();

        return url;
    }

    function wrapRequest(request) {
        var targetUrl = request.uri.getUrl();
        var headers = $.extend({}, request.headers);
        headers['x-azure-online-url'] = targetUrl;

        var downloadName = request.downloadName;
        if (downloadName) {
            headers['x-azure-online-download-name'] = downloadName;
        }

        var date = headers['Date'];
        if (date) {
            delete headers['Date'];
            headers['x-azure-online-date'] = date;
        }

        var contentLength = headers['Content-Length'];
        if (contentLength) {
            delete headers['Content-Length'];
            headers['x-azure-online-content-length'] = contentLength;
        }

        var contentType = headers['Content-Type'];
        if (contentType) {
            headers['x-azure-online-content-type'] = contentType;
        }

        var base64 = request.acceptBase64;
        if (base64) {
            headers['x-azure-online-accept-base64'] = 'true';
        }

        var processData = true;
        var data = '';
        if (request.data) {
            if (typeof request.data == "string") {
                data = request.data;
            } else {
                data = new Uint8Array(request.data);
                //data = new Blob(request.data, { type: contentType });
                //headers['Content-Transfer-Encoding'] = 'binary';
                //data = request.data;
                processData = false;
            }
        }

        return {
            url: getBaseUrl() + '?rnd=' + Math.random(),
            type: request.verb,
            headers: headers,
            data: data,
            success: request.success,
            error: request.error,
            processData: processData
        };
    }

    function xhr(options) {

        var success = null;
        var error = null;
        var progress = null;

        var rawXhr = $.ajax({
            url: options.url,
            type: options.type,
            data: options.data,
            processData: options.processData,
            beforeSend: function (request) {
                Object.keys(options.headers || {}).forEach(function (k) {
                    request.setRequestHeader(k, options.headers[k]);
                });
            },
            success: function (data) {
                if (success) {
                    success(data, rawXhr);
                }
            },
            error: function (data) {
                if (error) {
                    error(data, rawXhr);
                }
            }
        });

        return {
            done: function (successHandler, errorHandler, progressHandler) {
                success = successHandler;
                error = errorHandler;
                progress = progressHandler;
            }
        };
    }

    function send(request, success, failed, progress) {

        var options = wrapRequest(request);

        var req = xhr({
            type: options.type,
            url: options.url,
            data: options.data,
            headers: options.headers,
            processData: options.processData
        });

        req.done(function (r, rawXhr) {
            if (success) success(parseRequest(r), rawXhr);
        }, function (r, rawXhr) {
            if (failed) failed(parseRequest(r.responseText), rawXhr);
        }, function (r) {
            if (progress) progress(r);
        });

    }

    this.getDownloadUrl = getDownloadUrl;
    this.send = send;
    this.setProxyType = function (type) {
        proxyType = type;
    };
}